package com.yq.websocket;

import android.annotation.SuppressLint;
import android.os.Bundle;

import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;

import android.text.TextUtils;

import com.yq.websocket.databinding.ActivityMainBinding;
import com.yq.websocket.socket.SocketClient;
import com.yq.websocket.socket.SocketServer;

import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ServerHandshake;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    private final String TAG = this.getClass().getSimpleName();
    private ActivityMainBinding binding;
    private boolean serverStarted = false;
    private boolean connected = false;
    @SuppressLint("ClickableViewAccessibility")
    private View.OnTouchListener listener = (view, motionEvent) -> {
//            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
//                //通知父控件不要干扰
//                view.getParent().requestDisallowInterceptTouchEvent(true);
//            }
        if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
            //通知父控件不要干扰
            view.getParent().requestDisallowInterceptTouchEvent(true);
        }
//            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
//                view.getParent().requestDisallowInterceptTouchEvent(false);
//            }
        return false;
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.toolbar);
        binding.toolbar.setTitle("WebSocket测试");

        binding.fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show());

        //server
        String ip = Utils.getIPAddress(this);
        binding.main.tvIP.setText(ip);
        int port = 15211;

        initServer(ip, port);
        initClient();

        //按钮点击事件
        binding.main.btnStartServer.setOnClickListener(v -> {
            if (serverStarted) {
                Toast.makeText(getApplicationContext(), "服务已启动", Toast.LENGTH_LONG).show();
                return;
            }
            SocketServer.startService(this, port);
        });
        binding.main.btnConnect.setOnClickListener(v -> {
            if (connected) {
                Toast.makeText(getApplicationContext(), "已连接", Toast.LENGTH_LONG).show();
                return;
            }
            SocketClient.connect(ip, port);

        });
        binding.main.btnDisconnect.setOnClickListener(v -> {
            SocketClient.disConnect();
            SocketServer.stopService();
        });
    }

    private void initClient() {
        //client
        SocketClient.setListener(new SocketClient.ClientListener() {

            @Override
            public void onOpen(ServerHandshake handShakeData) {
                runOnUiThread(() -> {
                    connected = true;
                    binding.main.btnConnect.setText("连接成功");
                    Toast.makeText(getApplicationContext(), "已连接至：" + SocketClient.getServerAddress(), Toast.LENGTH_LONG).show();
                });
            }

            @Override
            public void onError(Exception ex) {
                runOnUiThread(() -> {
                            Toast.makeText(getApplicationContext(), "连接失败，请重试", Toast.LENGTH_LONG).show();
                            binding.main.btnConnect.setText("连接失败");
                        }
                );
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                runOnUiThread(() -> {
                    connected = false;
                    binding.main.btnConnect.setText("连接服务");
                });
            }

            @Override
            public void onMessage(String message) {
                runOnUiThread(() -> {
                    binding.main.tvServer.append("\n");
                    binding.main.tvServer.append("服务端：" + message);
                    binding.main.etServer.setText("");

                    binding.main.tvClient.append("\n");
                    binding.main.tvClient.append("接收到服务端信息：" + message);

                    scrollText(binding.main.tvServer);
                    scrollText(binding.main.tvClient);
                });
            }
        });

        binding.main.btnClientSend.setOnClickListener(v -> {
            if (!connected) {
                Toast.makeText(getApplicationContext(), "服务未连接", Toast.LENGTH_LONG).show();
                return;
            }
            String text = binding.main.etClient.getText().toString().trim();
            if (TextUtils.isEmpty(text)) {
                Toast.makeText(getApplicationContext(), "请输入内容", Toast.LENGTH_SHORT).show();
                return;
            }
            SocketClient.sendMsg(text);
        });

        binding.main.tvClient.setMovementMethod(ScrollingMovementMethod.getInstance());
        binding.main.tvClient.setOnTouchListener(listener);
    }

    private void initServer(String ip, int port) {
        SocketServer.setListener(new SocketServer.ServerStateListener() {
            @Override
            public void onStart() {
                runOnUiThread(() -> {
                    serverStarted = true;
                    binding.main.tvIP.setText(String.format("当前地址：%s:%s,%s", ip, port, "启动成功"));
                });
            }

            @Override
            public void onMessage(WebSocket conn, String message) {
                runOnUiThread(() -> {
                    binding.main.tvServer.append("\n");
                    binding.main.tvServer.append("接收到客户端消息：" + message);

                    binding.main.tvClient.append("\n");
                    binding.main.tvClient.append("客户端：" + message);
                    binding.main.etClient.setText("");

                    scrollText(binding.main.tvServer);
                    scrollText(binding.main.tvClient);
                });
            }

            @Override
            public void onError(WebSocket conn, Exception ex) {
                runOnUiThread(() -> {
                    Log.d(TAG, "onError: ");
                    serverStarted = false;
                    binding.main.tvIP.setText(String.format("当前IP：%s,Error:%s", ip, ex.getMessage()));
                });
            }

            @Override
            public void onClose(WebSocket conn, int code, String reason, boolean remote) {
                runOnUiThread(() -> {
                    Log.d(TAG, "onClose: ===");
                    serverStarted = false;
                    binding.main.tvIP.setText(ip);
                });
            }
        });

        binding.main.btnServerSend.setOnClickListener(v -> {
            if (!connected) {
                Toast.makeText(getApplicationContext(), "服务未连接", Toast.LENGTH_LONG).show();
                return;
            }
            String text = binding.main.etServer.getText().toString().trim();
            if (TextUtils.isEmpty(text)) {
                Toast.makeText(getApplicationContext(), "请输入内容", Toast.LENGTH_SHORT).show();
                return;
            }
            SocketServer.sendMsg(text);
        });
        binding.main.tvServer.setMovementMethod(ScrollingMovementMethod.getInstance());
        binding.main.tvServer.setOnTouchListener(listener);
    }

    private void scrollText(TextView textview) {
        int offset = textview.getLineCount() * textview.getLineHeight();
        if (offset > textview.getHeight())
            textview.scrollTo(0, offset - textview.getHeight() + textview.getLineHeight());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SocketClient.release();
        SocketServer.stopService();
    }
}